AddCSLuaFile( "config.lua" )
AddCSLuaFile( "defines.lua" )
AddCSLuaFile( "shared.lua" )
AddCSLuaFile( "cl_init.lua" )
AddCSLuaFile( "cl_umsg.lua" )
AddCSLuaFile( "cl_hud.lua" )
AddCSLuaFile( "cl_scoreboard.lua" )
AddCSLuaFile( "cl_spawnmenu.lua" )
include( "config.lua" )
include( "defines.lua" )
include( "shared.lua" )
include( "sh_func.lua" )
include( "cl_scoreboard.lua" )

function CCSpawnSWEP( player, command, arguments )
	//I don't think so, Tim.
	return
end
concommand.Add( "gm_giveswep", CCSpawnSWEP )

function ToggleCamera(ply, cmd, args)
	local spectating = ply:GetNetworkedBool("spectating")
	local cam = ply:GetNetworkedEntity("gb_cam")
	if(spectating) then
		if(gb_CurrentRound == 1) then
			ply:UnSpectate()
			ply:Give( "gmod_tool" )
			ply:Give( "gmod_camera" )
			ply:Give( "weapon_physgun" )
			ply:SetNetworkedBool("spectating", false)
			return
		else
			ply:UnSpectate()
			ply:Spectate( OBS_MODE_ROAMING )
			ply:SetNetworkedBool("spectating", false)
			return
		end
	elseif(!spectating) then
		if(cam:IsValid()) then
			ply:UnSpectate()
			ply:Spectate( OBS_MODE_CHASE )
			ply:SpectateEntity(cam)
			ply:StripWeapons()
			ply:SetNetworkedBool("spectating", true)
			return
		else
			ply:PrintMessage(HUD_PRINTTALK, "You do not have a camera!")	
			return
		end
	end
end
concommand.Add("gb_togglecam", ToggleCamera)

KaboomTable = {}
function Kaboom()
	if table.getn(KaboomTable) == 0 then return end //nothing to blow up
	local ent = KaboomTable[1]
	if (ent != nil && ent:IsValid()) then
		//MsgAll("                                   kaboom ran with valid ent\n")
		local vPoint = ent:GetPos()
		local effectdata = EffectData()
		effectdata:SetStart( vPoint )
		effectdata:SetOrigin( vPoint )
		effectdata:SetScale( 2 )
		util.Effect( "Explosion", effectdata )
		ent.Remove(ent)
	else
		//MsgAll("                                   kaboom ran with invalid ent\n")
	end
	table.remove(KaboomTable, 1)
end
timer.Create("kaboom", 0.1, 0, Kaboom)

function DestroyRobot(player)
	//MsgAll("                      destroy robot called\n")
	local RemoveMe = {"gb_cam", "gb_core", "gmod_thruster", "gmod_wheel", "prop_physics"} //delete all of these
	for k, TypeToRemove in pairs(RemoveMe) do
		local playerents = ents.FindByClass(TypeToRemove)
		for k, ent in pairs(playerents) do
			if ent:IsValid() then
				if ent:GetVar( "Founder", "nothing" ) == player then
					//MsgAll("                                    destroy robot added: "..tostring(ent).."\n")
					table.insert( KaboomTable, ent )
				end
			end
		end
	end
end

function PlayerForfeit( player, command, arguments )
	//MsgAll("                                           forfeit called\n")
	if gb_CurrentRound == 1 then
		player:ChatPrint("You can only forfeit during the fight.")
		return
	end
	DestroyRobot(player)
end
concommand.Add("gb_forfeit", PlayerForfeit)

function GM:PlayerDisconnected( ply )
	local entlist = ents.GetAll()
	for k, ent in pairs(entlist) do
		if ent:GetVar( "Founder", "nothing" ) == ply then
			ent.Remove(ent)
		end
	end
end

function CCSpawnSENT( player, command, arguments )
	local AllowedSENTs = { "gb_cam", "gb_core" }
	if ( arguments[1] == nil || !table.HasValue( AllowedSENTs, arguments[1] ) || gb_CurrentRound != 1 ) then return end

	local sent = scripted_ents.GetStored( arguments[1] )
	if (sent == nil) then return end

	sent = sent.t

	if (!sent.SpawnFunction) then return end

	if ( !gamemode.Call( "PlayerSpawnSENT", player, arguments[1] ) ) then return end

	local vStart = player:GetShootPos()
	local vForward = player:GetAimVector()
	local trace = {}
	trace.start = vStart
	trace.endpos = vStart + (vForward * 2048)
	trace.filter = player
	local tr = util.TraceLine( trace )
	local entity = sent:SpawnFunction( player, tr )

	if ( entity ) then
		gamemode.Call( "PlayerSpawnedSENT", player, entity )

		undo.Create("SENT")
			undo.SetPlayer(player)
			undo.AddEntity(entity)
		undo.Finish( "Scripted Entity ("..tostring(arguments[1])..")" )

		player:AddCleanup( "sents", entity )		
		entity:SetVar( "Player", player )
	end
end
concommand.Add( "gm_spawnsent", CCSpawnSENT )

function CCSpawnNPC( player, command, arguments )
	return
end
concommand.Add( "gmod_spawnnpc", CCSpawnNPC )

function CCSpawnVehicle( player, command, arguments )
	return
end
concommand.Add( "gm_spawnvehicle", CCSpawnVehicle )

function CCSpawn( player, command, arguments )
	if gb_CurrentRound != 1 then return end

	if ( arguments[1] == nil ) then return end
	if ( !gamemode.Call( "PlayerSpawnObject", player ) ) then return end
	if ( !util.IsValidProp( arguments[1] ) ) then return end

	GMODSpawnProp( player, arguments[1] )
end
concommand.Add( "gm_spawn", CCSpawn )

function PropSizeCheck( player, model )
	local prop = DoPlayerEntitySpawn( player, "prop_physics", model )
	local min,max = prop:WorldSpaceAABB()
	local size = min:Distance(max)
	prop:Remove()

	if size > gb_MaxPropSize then
		player:ChatPrint("That prop is too big.")
		return false
	end
	return true
end
hook.Add("PlayerSpawnProp", "Prop Size Check", PropSizeCheck)

function GM:ShowHelp( ply )
end

function ShowF1Menu( player )
	umsg.Start("ShowF1Menu", player)
	umsg.End()
end
hook.Add("ShowHelp", "F1Menu", ShowF1Menu)  

function ShowF2Menu( player )
	umsg.Start("ShowF2Menu", player)
	umsg.End()
end
hook.Add("ShowTeam", "F2Menu", ShowF2Menu)  

function ShowF3Menu( player )
	umsg.Start("ShowF3Menu", player)
	umsg.End()
end
hook.Add("ShowSpare1", "F3Menu", ShowF3Menu)

function ShowF4Menu( player )
	umsg.Start("ShowF4Menu", player)
	umsg.End()
end
hook.Add("ShowSpare2", "F4Menu", ShowF4Menu)

function GM:CanTool( pl, tr, toolmode )
	//MsgAll("                  toolmode: "..tostring(toolmode).."\n")
	if !table.HasValue( AllowableTools, toolmode ) then
		pl:PrintMessage(HUD_PRINTTALK, "That tool is not allowed.")
		return false
	end

	local trent = tr.Entity
	if ((!trent:IsValid() && !trent:IsWorld()) || trent:IsPlayer() || (trent:IsWorld() && !table.HasValue( AllowableWorldTools, toolmode ))) then
		return false
	elseif (trent:IsWorld() && table.HasValue( AllowableWorldTools, toolmode )) then
		return true
	end

	if (!trent:GetVar( "Founder", "nothing" )) then //unowned
		trent:SetVar( "Founder", pl ) //own it
	end

	if trent:GetVar( "Founder", "nothing" ) == pl then
		return GAMEMODE.BaseClass:CanTool(pl, tr, toolmode)
	else
		pl:PrintMessage(HUD_PRINTTALK, "This is not your entity!")
		return false
	end
end

function GM:PlayerInitialSpawn( ply )
	self.BaseClass:PlayerInitialSpawn( ply )

	if (team.NumPlayers(2) > team.NumPlayers(1)) then
		ply:SetTeam( 1 )
	elseif (team.NumPlayers(2) < team.NumPlayers(1)) then
		ply:SetTeam( 2 )
	else
		ply:SetTeam( math.random(1,2) )
	end

	if gb_CurrentRound != 1 then
		ply:StripWeapons()
		ply:Spectate( OBS_MODE_ROAMING )
	end

	umsg.Start("changeround", ply)
		umsg.Long(gb_CurrentRound)
	umsg.End()

	umsg.Start("updateteamcores", ply)
		umsg.Long(gb_NumRedCores)
		umsg.Long(gb_NumBlueCores)
	umsg.End()
end

function GM:PlayerSpawn( ply )
	self.BaseClass:PlayerSpawn( ply )
	ply:ShouldDropWeapon(false)//fix the spectator with gun bug

	if gb_CurrentRound != 1 then
		// Put them into spectator mode
		local cam = ply:GetNetworkedEntity("gb_cam")
		if(cam:IsValid()) then
			ply:Spectate( OBS_MODE_CHASE )
			ply:SpectateEntity(cam)
			ply:StripWeapons()
		else
			ply:Spectate( OBS_MODE_ROAMING )
			ply:StripWeapons()
		end
	end
end

function GM:PlayerSelectSpawn(pl)
	if pl:Team() == 2 then
		spawns = ents.FindByClass( "info_player_blue" )
		local randomspawn = math.random(#spawns)
		return spawns[randomspawn]
	
	elseif pl:Team() == 1 then
		spawns = ents.FindByClass( "info_player_red" )
		local randomspawn = math.random(#spawns)
		return spawns[randomspawn]
	end
end

function GM:PlayerNoClip(ply)
	if ply:IsAdmin() then
		return true
	else
		return false
	end
end

function GM:PlayerSpawnedProp( ply, model, prop )
	prop:SetVar( "Founder", ply )

	self.BaseClass:PlayerSpawnedProp( ply, model, prop )

	local color = team.GetColor( ply:Team() )

	// Set the color
	prop:SetColor(color.r, color.g, color.b, color.a)
	local physob = prop:GetPhysicsObject()
	if physob then
		local propmass = physob:GetMass()
		local min,max = prop:WorldSpaceAABB()
		local size = min:Distance(max)
		prop.aHealth = (size * 0.001) * propmass
	end
end

function GM:PlayerSpawnedSENT( ply, prop )
	prop:SetVar( "Founder", ply )

	self.BaseClass:PlayerSpawnedSENT(ply, prop)
end

function GM:EntityTakeDamage( ent, inflictor, attacker, amount )
	if (ent:IsWorld() || ent:IsPlayer() || ent:GetClass() == "gb_core" || gb_CurrentRound == 1) then return end

	//if(ent:GetOwner() == nil) then return end //what are you doing with this lua?

	if(ent.aHealth == nil) then
		local physob = prop:GetPhysicsObject()
		if physob then
			local propmass = physob:GetMass()
			local min,max = prop:WorldSpaceAABB()
			local size = min:Distance(max)
			ent.aHealth = (size * 0.001) * propmass
		end
	end

	ent.aHealth = ent.aHealth - amount

	if(ent.aHealth <= 0) then
		constraint.RemoveAll(ent)
	end

	if(ent.aHealth < -100) then
		local vPoint = ent:GetPos(self)
		local effectdata = EffectData()
		effectdata:SetStart( vPoint )
		effectdata:SetOrigin( vPoint )
		effectdata:SetScale( 2 )
		util.Effect( "Explosion", effectdata )
		util.Effect( "cball_explode", effectdata )
		ent.Remove(ent)
	end
end

function GM:CanPlayerEnterVehicle( player, vehicle, role )
	if gb_CurrentRound != 1 then 
		return false
	end
end

function GM:PlayerLoadout(ply)
	if gb_CurrentRound == 1 then
		ply:Give( "gmod_tool" )
		ply:Give( "gmod_camera" )
		ply:Give( "weapon_physgun" )
	end
	return true
end

function GM:PhysgunPickup(ply, ent)
	if (ent:IsPlayer() && !ply:IsAdmin()) then return end

	if (!ent:GetVar( "Founder", "nothing" )) then //unowned
		ent:SetVar( "Founder", ply ) //own it
	end

	if (ent:GetVar( "Founder", "nothing" ) == ply || ply:IsAdmin()) then
		return true
	end
	return false
end

function GetPropHealth(ply, cmd, args)
	local traceres = ply:GetEyeTrace()
	local ent = traceres.Entity
	if(!ent:IsValid() || ent:IsWorld() || ent:IsPlayer() || ent:GetClass() != "prop_physics") then
		ply:PrintMessage(HUD_PRINTTALK, "You must be looking at a prop to do this!")
	else
		ply:PrintMessage(HUD_PRINTTALK, "Total Prop Health: " .. ent.aHealth)
	end
end
concommand.Add("gethealth", GetPropHealth)